#!/usr/bin/env node --no-warnings --experimental-modules
// #!/usr/bin/env node

// 后端监控系统 - Node.js服务
// 包含WebSocket服务器、游戏记录查询、数据处理、邮件发送等功能
const WebSocket = require('ws');
const http = require('http');
const nodemailer = require('nodemailer');
const axios = require('axios');

// 配置信息
let clientConfig = {
    interval: 30,
    email1001: '13107463918@163.com',
    email1004: 'chengzi1688cz.com',
    maxAlert: 5000,
    minAlert: -5000
};

// 邮件配置 - 需要用户配置
const emailConfig = {
    host: 'smtp.163.com', // 邮件服务器地址
    port: 465, // 端口
    secure: true, // 使用SSL
    auth: {
        user: '13935902500@163.com', // 发送邮箱
        pass: 'WMgysKaycfQR3QJY' // 邮箱密码或授权码
    }
};

// 游戏API配置
const gameApiConfig = {
    host: 'https://admin-m2,ddnet66.com/', // 游戏API地址
};

// 创建邮件传输器
let transporter = null;

// 初始化邮件服务
function initEmailService() {
    try {
        transporter = nodemailer.createTransport(emailConfig);
        console.log('邮件服务初始化成功');
    } catch (error) {
        console.error('邮件服务初始化失败:', error.message);
    }
}

// 创建HTTP服务器
const server = http.createServer();

// 创建WebSocket服务器
const wss = new WebSocket.Server({ server });

// 存储客户端连接
const clients = new Set();

// WebSocket连接处理
wss.on('connection', function connection(ws) {
    console.log('新的客户端连接');
    clients.add(ws);

    // 发送连接成功消息
    sendToClient(ws, {
        type: 'log',
        message: 'WebSocket连接成功',
        level: 'success'
    });

    // 处理客户端消息
    ws.on('message', function incoming(message) {
        try {
            const data = JSON.parse(message);
            handleClientMessage(ws, data);
        } catch (error) {
            console.error('解析客户端消息失败:', error.message);
            sendToClient(ws, {
                type: 'log',
                message: '消息格式错误',
                level: 'error'
            });
        }
    });

    // 连接关闭处理
    ws.on('close', function () {
        console.log('客户端连接关闭');
        clients.delete(ws);
    });

    // 错误处理
    ws.on('error', function (error) {
        console.error('WebSocket错误:', error.message);
        clients.delete(ws);
    });
});

// 处理客户端消息
function handleClientMessage(ws, data) {
    console.log('收到客户端消息:', data);
    switch (data.type) {
        case 'config':
            // 更新配置
            clientConfig = { ...clientConfig, ...data.data };
            console.log('收到客户端配置:', clientConfig);
            sendToClient(ws, {
                type: 'log',
                message: '配置已更新',
                level: 'success'
            });
            break;

        case 'ping':
            // 心跳响应
            sendToClient(ws, { type: 'pong' });
            break;

        case 'alert':
            // 处理预警数据
            handleAlert(data.data);
            break;
        case 'testsend':
            // 测试发送邮件
            testSendEmail();
            break;

        default:
            console.log('未知消息类型:', data.type);
    }
}

// 发送消息到客户端
function sendToClient(ws, message) {
    if (ws.readyState === WebSocket.OPEN) {
        ws.send(JSON.stringify(message));
    }
}

// 广播消息到所有客户端
function broadcastToClients(message) {
    clients.forEach(client => {
        sendToClient(client, message);
    });
}

// 处理预警数据
async function handleAlert(alertData) {
    try {
        console.log('处理预警数据:', alertData);

        // 通知前端开始处理
        broadcastToClients({
            type: 'log',
            message: `开始处理 ${alertData.type} 的数据记录`,
            level: 'info'
        });

        // 请求游戏记录表
        const gameRecords = await getGameRecords();

        if (gameRecords && gameRecords.length > 0) {
            // 处理游戏记录详情
            const processedData = await processGameRecords(gameRecords);

            // 通知前端数据准备完毕
            broadcastToClients({
                type: 'log',
                message: `${alertData.type} 数据已准备完毕，正在发送邮件`,
                level: 'info'
            });

            // 发送邮件
            await sendAlertEmail(alertData, processedData);

            // 通知前端邮件发送成功
            broadcastToClients({
                type: 'log',
                message: `${alertData.type} 的游戏数据邮件发送成功`,
                level: 'success'
            });
        } else {
            broadcastToClients({
                type: 'log',
                message: '未获取到游戏记录数据',
                level: 'warning'
            });
        }

    } catch (error) {
        console.error('处理预警数据失败:', error.message);
        broadcastToClients({
            type: 'log',
            message: `处理预警数据失败: ${error.message}`,
            level: 'error'
        });
    }
}

// 获取游戏记录表
async function getGameRecords() {
    try {
        const url = `${gameApiConfig.host}/Log/LogGameTable?page=1&limit=200&compet`;
        const params = {
            size: 200
        };

        console.log('请求游戏记录表:', url);

        const response = await axios.get(url, { params });

        if (response.data && response.data.code === 200) {
            console.log(`获取到 ${response.data.data.length} 条游戏记录`);
            return response.data.data;
        } else {
            throw new Error('游戏记录接口返回错误');
        }

    } catch (error) {
        console.error('获取游戏记录失败:', error.message);
        throw error;
    }
}

// 处理游戏记录详情
async function processGameRecords(gameRecords) {
    const processedData = [];

    try {
        console.log('开始处理游戏记录详情');

        // 限制并发请求数量
        const batchSize = 5;

        for (let i = 0; i < gameRecords.length; i += batchSize) {
            const batch = gameRecords.slice(i, i + batchSize);

            const batchPromises = batch.map(async (record) => {
                try {
                    const details = await getGameRecordDetails(record.RecordId);
                    return {
                        recordId: record.RecordId,
                        details: details
                    };
                } catch (error) {
                    console.error(`处理记录 ${record.RecordId} 失败:`, error.message);
                    return null;
                }
            });

            const batchResults = await Promise.all(batchPromises);
            processedData.push(...batchResults.filter(result => result !== null));

            // 进度通知
            const progress = Math.min(i + batchSize, gameRecords.length);
            broadcastToClients({
                type: 'log',
                message: `处理进度: ${progress}/${gameRecords.length}`,
                level: 'info'
            });
        }

        console.log(`游戏记录详情处理完成，共处理 ${processedData.length} 条记录`);
        return processedData;

    } catch (error) {
        console.error('处理游戏记录详情失败:', error.message);
        throw error;
    }
}

// 获取游戏记录详情
async function getGameRecordDetails(recordId) {
    try {
        const url = `${gameApiConfig.host}/Log/LogGameScoreTable`;
        const params = {
            page: 1,
            limit: 20,
            recordId: recordId
        };

        const response = await axios.get(url, { params });

        if (response.data && response.data.code === 200 && response.data.data.length > 0) {
            // 过滤非机器人数据
            const playerData = response.data.data
                .filter(item => !item.IsRobot)
                .map(item => `${item.GameId}(${item.Name}) 得分：${item.Score}`);

            return playerData;
        } else {
            return [];
        }

    } catch (error) {
        console.error(`获取记录详情失败 (RecordId: ${recordId}):`, error.message);
        throw error;
    }
}

// 发送预警邮件
async function sendAlertEmail(alertData, gameData) {
    if (!transporter) {
        throw new Error('邮件服务未初始化');
    }

    try {
        // 确定收件人
        const recipient = alertData.type === '1001' ? clientConfig.email1001 : clientConfig.email1004;

        // 生成邮件内容
        const emailContent = generateEmailContent(alertData, gameData);

        // 邮件选项
        const mailOptions = {
            from: emailConfig.auth.user,
            to: recipient,
            subject: `游戏数据预警 - ${alertData.type} - ${new Date().toLocaleString()}`,
            html: emailContent
        };

        // 发送邮件
        const result = await transporter.sendMail(mailOptions);
        console.log('邮件发送成功:', result.messageId);

        return result;

    } catch (error) {
        console.error('发送邮件失败:', error.message);
        throw error;
    }
}

// 生成邮件内容
function generateEmailContent(alertData, gameData) {
    const currentTime = new Date().toLocaleString();

    let html = `
        <div style="font-family: Arial, sans-serif; max-width: 800px; margin: 0 auto;">
            <h2 style="color: #333; border-bottom: 2px solid #1E9FFF; padding-bottom: 10px;">
                游戏数据预警通知
            </h2>
            
            <div style="background: #f9f9f9; padding: 15px; border-radius: 5px; margin: 20px 0;">
                <h3 style="color: #666; margin-top: 0;">预警信息</h3>
                <p><strong>预警类型:</strong> ${alertData.type}</p>
                <p><strong>预警时间:</strong> ${currentTime}</p>
                <p><strong>预警原因:</strong> ${alertData.message}</p>
                <p><strong>数据值:</strong> ${alertData.value}</p>
            </div>
            
            <div style="margin: 20px 0;">
                <h3 style="color: #666;">游戏数据详情</h3>
                <p>共处理 <strong>${gameData.length}</strong> 条游戏记录</p>
            </div>
            
            <div style="margin: 20px 0;">
                <h4 style="color: #666;">详细数据:</h4>
                <div style="max-height: 400px; overflow-y: auto; border: 1px solid #ddd; padding: 10px;">
    `;

    // 添加游戏数据
    gameData.forEach((record, index) => {
        html += `
            <div style="margin-bottom: 15px; padding: 10px; background: ${index % 2 === 0 ? '#f5f5f5' : '#fff'}; border-radius: 3px;">
                <h5 style="margin: 0 0 5px 0; color: #333;">记录 ${record.recordId}</h5>
        `;

        if (record.details && record.details.length > 0) {
            record.details.forEach(detail => {
                html += `<p style="margin: 2px 0; font-size: 14px; color: #666;">${detail}</p>`;
            });
        } else {
            html += `<p style="margin: 2px 0; font-size: 14px; color: #999;">无详细数据</p>`;
        }

        html += `</div>`;
    });

    html += `
                </div>
            </div>
            
            <div style="margin-top: 30px; padding: 15px; background: #e8f4fd; border-radius: 5px;">
                <p style="margin: 0; color: #666; font-size: 12px;">
                    此邮件由游戏监控系统自动发送，请勿回复。<br>
                    发送时间: ${currentTime}
                </p>
            </div>
        </div>
    `;

    return html;
}

// 启动服务器
function startServer() {
    const PORT = process.env.PORT || 3001;

    server.listen(PORT, function () {
        console.log(`监控服务器启动成功，端口: ${PORT}`);
        console.log(`WebSocket地址: ws://localhost:${PORT}`);
    });
}

// 错误处理
process.on('uncaughtException', function (error) {
    console.error('未捕获的异常:', error);
});

process.on('unhandledRejection', function (reason, promise) {
    console.error('未处理的Promise拒绝:', reason);
});

// 关闭
process.on('SIGINT', function () {
    console.log('\n正在关闭服务器...');

    // 关闭所有WebSocket连接
    clients.forEach(client => {
        if (client.readyState === WebSocket.OPEN) {
            client.close();
        }
    });

    // 关闭服务器
    server.close(function () {
        console.log('服务器已关闭');
        process.exit(0);
    });
});

// 初始化并启动服务
initEmailService();
startServer();




// 发送预警邮件
async function testSendEmail() {
    if (!transporter) {
        throw new Error('邮件服务未初始化');
    }

    try {
        // 邮件选项
        const mailOptions = {
            from: emailConfig.auth.user,
            to: '1261879717@qq.com',
            subject: `巴拉巴拉小魔仙`,
            html: '<p>变身变身</p>'
        };
        // 发送邮件
        const result = await transporter.sendMail(mailOptions);
        console.log('邮件发送成功:', result.messageId);

        return result;

    } catch (error) {
        console.error('发送邮件失败:', error.message);
        throw error;
    }
}



// 导出模块（如果需要在其他文件中使用）
module.exports = {
    server,
    wss,
    broadcastToClients,
    clientConfig
};